<template>
  <div>
    <button @click="onClick">按钮</button>
    <button @click="onClick3">按钮2</button>
  </div>
</template>

<script setup lang="ts">
import axios, { AxiosInstance, CancelTokenSource } from "axios";
import "reflect-metadata";
import { useIndex } from "./useIndex";

const { onClick, onClick3 } = useIndex();

class HttpClient {
  private instance: AxiosInstance;
  private cancelTokenSource: CancelTokenSource;

  constructor() {
    this.instance = axios.create();
    this.cancelTokenSource = axios.CancelToken.source();

    this.instance.interceptors.request.use((config) => {
      // 在请求头中添加自定义逻辑
      return config;
    });

    this.instance.interceptors.response.use(
      (response) => {
        // 处理响应结果，例如对特定状态码进行处理等
        return response.data;
      },
      (error) => {
        // 处理请求错误
        if (axios.isCancel(error)) {
          // 请求被取消
        } else {
          // 其他错误
        }
        throw error;
      }
    );
  }

  public get(url: string, config?: any): Promise<any> {
    return this.instance.get(url, {
      ...config,
      cancelToken: this.cancelTokenSource.token,
    });
  }

  public post(url: string, data?: any, config?: any): Promise<any> {
    return this.instance.post(url, data, {
      ...config,
      cancelToken: this.cancelTokenSource.token,
    });
  }

  public delete(url: string, config?: any): Promise<any> {
    return this.instance.delete(url, {
      ...config,
      cancelToken: this.cancelTokenSource.token,
    });
  }

  public put(url: string, data?: any, config?: any): Promise<any> {
    return this.instance.put(url, data, {
      ...config,
      cancelToken: this.cancelTokenSource.token,
    });
  }

  public cancelRequest(): void {
    this.cancelTokenSource.cancel("请求被取消");
  }

  public onProgress(callback: (progressEvent: ProgressEvent) => void): void {
    this.instance.defaults.onUploadProgress = callback;
    this.instance.defaults.onDownloadProgress = callback;
  }
}

class A {
  name: string;
  age: number;
  constructor() {
    this.name = "小明";
    this.age = 18;
  }
}

// const Base = (base: string) => {
//   return <T extends { new (...args: any[]): {} }>(target: T) => {
//     return class extends target {
//       static base = base;
//     };
//   };
// };

const Base = (base: string) => {
  const fn: ClassDecorator = (target) => {
    target.prototype.base = "base";
    // target.base = base;
  };
  return fn;
};

const Get = (url: string) => {
  const fn: MethodDecorator = (target, key, descriptor: PropertyDescriptor) => {
  };
  return fn;
};

@Base("/api")
class Test {
  // base: string; // 添加一个静态属性来存储装饰器的值

  @Get("/test")
  static get(a, b, c) {
    console.log(a, b, c); // undefined
    // return Test.base;
  }
}

// 使用示例
// const httpClient = new HttpClient();

// httpClient
//   .get("https://api.apiopen.top/api/getHaoKanVideo?page=0&size=10")
//   .then((response) => {
//     console.log(response);
//   })
//   .catch((error) => {
//     console.error(error);
//   });

// setTimeout(() => {
//   // httpClient.cancelRequest();
// }, 10);
// // 取消请求

// 监听请求进度
// httpClient.onProgress((progressEvent) => {
//   console.log(
//     `上传/下载进度:${(progressEvent.loaded / progressEvent.total) * 100}%`
//   );
// });

const onClick2 = async () => {
  // console.log(26, http);
  //  const a = await  http.getUserList()
  // -----------------
  // const user = new User();
  // console.log(48, user);
  // // user.getUserById(1)
  // user
  //   .getUserById(1)
  //   .then((data) => {
  //     console.log(53, data);
  //   })
  //   .catch((error) => {
  //     console.error(56, error);
  //   });

  // -----------------

  // const test = new Test();
  // console.log(147, test,test.get());
  // console.log(Test.get(4, 5, 6)); // undefined

  // ---------------

  const Base = (base: string) => {
    const fn: ClassDecorator = (target) => {
      target.prototype.base = base;
      // Reflect;
    };
    return fn;
  };

  const Get = (url: string) => {
    const fn: MethodDecorator = (
      target,
      key,
      descriptor: PropertyDescriptor
    ) => {
      console.log(target.constructor.prototype.base); // 可以正确访问到类装饰器添加到原型上的属性
    };
    return fn;
  };

  @Base("base value")
  class MyClass {
    @Get("http://example.com")
    myMethod() {
      // 方法体
    }
  }

  const instance = new MyClass();
  instance.myMethod(); // 输出 'base value'
};
</script>

<style scoped></style>
